package com.thz.friend.service.analysis.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.thz.common.core.constants.Constants;
import com.thz.common.core.constants.HttpConstants;
import com.thz.common.core.enums.ResultCode;
import com.thz.common.core.pojo.LoginUser;
import com.thz.common.core.pojo.vo.LoginUserVO;
import com.thz.common.core.result.Result;
import com.thz.common.core.utlis.ThreadLocalUtil;
import com.thz.exception.ApplicationException;
import com.thz.friend.controller.exam.ExamController;
import com.thz.friend.mapper.analysis.LearningReportMapper;
import com.thz.friend.mapper.analysis.StudentLearningDataMapper;
import com.thz.friend.mapper.blog.BlogMapper;
import com.thz.friend.mapper.course.CourseMapper;
import com.thz.friend.mapper.exam.ExamQuestionMapper;
import com.thz.friend.mapper.registration.CourseRegistrationMapper;
import com.thz.friend.mapper.report.ReportMapper;
import com.thz.friend.mapper.user.UserExamMapper;
import com.thz.friend.mapper.user.UserMapper;
import com.thz.friend.mapper.user.UserSubmitMapper;
import com.thz.friend.mapper.video.VideoMapper;
import com.thz.friend.pojo.analysis.LearningReport;
import com.thz.friend.pojo.analysis.StudentLearningData;
import com.thz.friend.pojo.analysis.vo.CourseReport;
import com.thz.friend.pojo.course.Course;
import com.thz.friend.pojo.exam.ExamQuestion;
import com.thz.friend.pojo.exam.vo.ExamVO;
import com.thz.friend.pojo.question.Question;
import com.thz.friend.pojo.registration.CourseRegistration;
import com.thz.friend.pojo.report.Report;
import com.thz.friend.pojo.user.User;
import com.thz.friend.pojo.user.UserExam;
import com.thz.friend.pojo.user.UserSubmit;
import com.thz.friend.service.analysis.LearningAnalysisService;
import com.thz.friend.service.exam.IExamService;
import com.thz.security.service.TokenService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class LearningAnalysisServiceImpl implements LearningAnalysisService {

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private UserSubmitMapper userSubmitMapper;

    @Autowired
    private UserExamMapper userExamMapper;

    @Autowired
    private CourseRegistrationMapper courseRegistrationMapper;

    @Autowired
    private BlogMapper blogMapper;

    @Autowired
    private VideoMapper videoMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private IExamService examService;

    @Autowired
    private ExamQuestionMapper examQuestionMapper;


    @Value("${jwt.secret}")
    private String secret;


    @Override
    public String getReport(String token) {
        // 1.截取token并且解析
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        // 2.解析token
        LoginUser loginUser = tokenService.getLoginUser(token, secret);
        if (loginUser == null) {
            throw new ApplicationException(Result.failed(ResultCode.USER_GET_MESSAGE_ERROR));
        }

        Long userId = loginUser.getUserId();

        List<CourseReport> courseReports = getCourseRegistration(userId);

        StudentLearningData studentLearning = generateLearningReport(userId);

        User user = userMapper.selectById(userId);

        return buildReport(studentLearning,user.getNickName(),courseReports);
    }

    public StudentLearningData generateLearningReport(Long userId) {
        StudentLearningData studentLearningData = new StudentLearningData();
        studentLearningData.setCreateTime(LocalDateTime.now());
        studentLearningData.setCreateUser(userId);
        studentLearningData.setUserId(userId);
        studentLearningData.setCompletedCourses(getCompletedCourses(userId));
        studentLearningData.setHomeworkAverageScore(getHomeworkAverageScore(userId));
        studentLearningData.setChallengeSuccessRate(getChallengeSuccessRate(userId));
        return studentLearningData;
    }

    public List<CourseReport> getCourseRegistration(Long userId){
        List<CourseRegistration> courseRegistration = courseRegistrationMapper.selectList(new LambdaQueryWrapper<CourseRegistration>()
                .eq(CourseRegistration::getStudentId, userId));
        List<CourseReport> courseReports = new ArrayList<>();

        for (CourseRegistration registration : courseRegistration) {
            CourseReport courseReport = new CourseReport();
            Long courseId = registration.getCourseId();
            Course course = courseMapper.selectById(courseId);
            courseReport.setCourseName(course.getCourseName());
            Integer blogCount = reportMapper.selectCourseBlogCount(userId,courseId);
            Integer blog = blogMapper.selectCourseBlogCount(courseId);
            Integer videoCount = reportMapper.selectCourseVideoCount(userId,courseId);
            Integer video = videoMapper.selectCourseVideoCount(courseId);
            courseReport.setBlogCount(blogCount);
            courseReport.setVideoCount(videoCount);
            double blogPercent;
            if (blogCount > 0) {
                blogPercent = (double) blogCount / blog;
                String str = String.format("%.2f", blogPercent);
                blogPercent = Double.parseDouble(str);
            }else {
                blogPercent = 0.0;
            }
            courseReport.setBlogPercentage(blogPercent);
            double videoPercent;
            if (videoCount > 0) {
                videoPercent = (double) videoCount / video;
                String str = String.format("%.2f", videoPercent);
                videoPercent = Double.parseDouble(str);
            }else {
                videoPercent = 0.0;
            }
            courseReport.setVideoPercentage(videoPercent);
            courseReports.add(courseReport);
        }

        return courseReports;
    }

    public String  To(double d) {
        DecimalFormat df = new DecimalFormat("0.00%");
        return df.format(d);
    }


    private String buildReport(StudentLearningData studentLearning,String userNickName,List<CourseReport> courseReports){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("  ").append("尊敬的").append(userNickName).append(", 您的学习报告。完成的课程数量: ").append(studentLearning.getCompletedCourses()).append("。");
        for (CourseReport courseReport : courseReports) {
           stringBuilder.append("你加入了").append(courseReport.getCourseName()).append("课程，文章阅览了")
                   .append(courseReport.getBlogCount()).append("篇，完成率为").append(To(courseReport.getBlogPercentage())).append("。").append("视频学习了")
                   .append(courseReport.getVideoCount()).append("个，完成率为").append(To(courseReport.getVideoPercentage())).append("。");
        }

        stringBuilder.append("你的编程作业平均分: ").append(studentLearning.getHomeworkAverageScore()).append("，").append("编程挑战成功率: ").append(To(studentLearning.getChallengeSuccessRate())).append("。");
        return stringBuilder.toString();
    }

    private Integer getCompletedCourses(Long userId){
        return reportMapper.getCompletedCourses(userId);
    }

    private Double getHomeworkAverageScore(Long userId){
        List<CourseRegistration> courseRegistration = courseRegistrationMapper.selectList(new LambdaQueryWrapper<CourseRegistration>()
                .eq(CourseRegistration::getStudentId, userId));

        Integer score = 0;

        int Count = 0;
        for (CourseRegistration registration : courseRegistration) {
            List<ExamVO> examVOList = examService.listHomework(registration.getCourseId());
            for (ExamVO examVO : examVOList) {
                Count++;
                score += examVO.getScore();
            }
        }
        double averageScore = 0.0;
        if (score > 0 && Count > 0) {
            averageScore = (double) score / Count;
            String str = String.format("%.2f", averageScore);
            averageScore = Double.parseDouble(str);
        }
        return averageScore;
    }




    private Double getChallengeSuccessRate(Long userId){
        List<UserSubmit> userSubmitList = userSubmitMapper.selectExamPassList(userId);

        List<UserExam> userExamList = userExamMapper.selectList(new LambdaQueryWrapper<UserExam>()
                .select(UserExam::getExamId)
                .eq(UserExam::getUserId,userId));


        int questionCount = 0;
        for (UserExam userExam : userExamList) {
            List<ExamQuestion> examQuestionList = examQuestionMapper.selectList(new LambdaQueryWrapper<ExamQuestion>()
                    .select(ExamQuestion::getQuestionId)
                    .eq(ExamQuestion::getExamId,userExam.getExamId()));
            questionCount+=examQuestionList.size();
        }

        double registration = 0.0;
        int s = userSubmitList.size();
        if (s > 0 && questionCount > 0) {
            registration = (double) s / questionCount;
            String str = String.format("%.2f", registration);
            registration = Double.parseDouble(str);
        }
        return registration;

    }

} 